#include "multi_widget_combobox.h"
#include <QCheckBox>
#include <QListWidget>
#include <QStylePainter>

MultiWdgComboBox::MultiWdgComboBox(QWidget* parent) : QComboBox(parent)
{
	m_view_ptr = new QListWidget;
	m_view_ptr->setContentsMargins(QMargins(15, 0, 0, 0));

    setModel(m_view_ptr->model());
    setView(m_view_ptr);
}

void MultiWdgComboBox::addItem(const QString &text, const QVariant &userData)
{
	QListWidgetItem *pItem = new QListWidgetItem;
	QCheckBox* checkBox = new QCheckBox(this);
	checkBox->setText(text);
	pItem->setData(Qt::UserRole, userData);
	
	m_view_ptr->addItem(pItem);
	m_view_ptr->setItemWidget(pItem, checkBox);

	connect(checkBox, &QCheckBox::clicked, this, [this](bool checked)
	{
		auto box = static_cast<QCheckBox*>(sender());
		QStringList texts = m_text.isEmpty() ? QStringList() : m_text.split(";");
		if (checked)
		{
			texts.append(box->text());
		}
		else
		{
			texts.removeOne(box->text());
		}
		m_text = texts.join(";");
		update();
	});
}

void MultiWdgComboBox::setData(const QVariant& data)
{
	QStringList text;
	QVariantList datas = data.value<QVariantList>();
	for (int index = 0; index < m_view_ptr->count(); ++index)
	{
		auto item = m_view_ptr->item(index);
		auto ptr = static_cast<QCheckBox*>(m_view_ptr->itemWidget(item));
		if (datas.contains(item->data(Qt::UserRole)))
		{
			if (ptr != nullptr && ptr->isEnabled())
			{
				ptr->setChecked(true);
				text.push_back(ptr->text());
			}
		}
	}
	m_text = text.join(";");
}

QVariant MultiWdgComboBox::data() const
{
	QVariantList datas;
	for (int index = 0; index < m_view_ptr->count(); ++index)
	{
		auto item = m_view_ptr->item(index);
		auto ptr = static_cast<QCheckBox*>(m_view_ptr->itemWidget(item));
		if (ptr != nullptr && ptr->isChecked())
		{
			datas.push_back(item->data(Qt::UserRole));
		}
	}

	return datas;
}

void MultiWdgComboBox::paintEvent(QPaintEvent* e)
{
	QStylePainter painter(this);
	painter.setPen(palette().color(QPalette::Text));

	QStyleOptionComboBox opt;
	initStyleOption(&opt);
	painter.drawComplexControl(QStyle::CC_ComboBox, opt);

	if (opt.editable)
	{
		painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
		return;
	}

	QRect editRect = this->style()->subControlRect(QStyle::CC_ComboBox, &opt, QStyle::SC_ComboBoxEditField, this);

	QStyleOptionButton buttonOpt;
	buttonOpt.initFrom(this);
	buttonOpt.direction = Qt::LeftToRight;
	buttonOpt.rect = editRect;
	buttonOpt.text = m_text;
	buttonOpt.icon = opt.currentIcon;
	buttonOpt.iconSize = opt.iconSize;
	painter.drawControl(QStyle::CE_CheckBoxLabel, buttonOpt);
}
